/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hiberengine;

import appClient.UserComman;
import com.google.gson.Gson;
import engine.Address;
import engine.City;
import engine.Country;
import engine.FullPersone;
import engine.Persone;
import engine.Phone;
import engine.Singleton;
import engine.Street;
import engine.TypeAdress;
import engine.TypePhone;
import hibernate.Roll;
import hibernate.Teltype;
import hibernate.User;
import hibertest.DAOPersone;
import hibertest.HibernateUtil;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import listener.MyEvent;
import listener.MyListener;
import listener.MyrealListener;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.springframework.beans.factory.annotation.Autowired;
import protocol.Command;
import server.Player;
import server.ServeOneThread;

/**
 *
 * @author User
 */
public class MyQuery implements MyListener {

    @Override
    public boolean autorize(MyEvent e) {
        String name = e.data;
        String pass = e.add;
        try {
            DAOPersone n = new DAOPersone();
            User user = n.getUserByLogin(name);
            String passSql = user.getPass();
            String usId = user.getId();
            String roll = user.getRollId().getNroll();

            Player palyer = Singleton.clients.get(Singleton.clients.size()-1);
            Command obj = new Command();
            obj.Type = "Connect";
            if (!passSql.equals(pass))
            {
                obj.Data = "Error";
                Gson gson = new Gson();
                String send = gson.toJson(obj);
                palyer.getSrv().sendUser(send);
               // vis.getCli().refuse("{\"Type\": \"End\"}");
            }
            else{

                obj.Data = roll;
                obj.Add = usId;
                Gson gson = new Gson();
                String send = gson.toJson(obj);
                palyer.getSrv().sendUser(send);

                palyer.setLogin(name);
                palyer.setId(usId);
                palyer.setRole(roll);
            }
        } catch (Exception ex)
          {
            //  log.info("test" + e);
            Player palyer = Singleton.clients.get(Singleton.clients.size()-1);
            Command obj = new Command();
            obj.Type = "Connect";
            obj.Data = "Error";
            Gson gson = new Gson();
            String send = gson.toJson(obj);
            try {
                palyer.getSrv().sendUser(send);
            }
            catch (Exception exp)
            {
                System.out.println("No Server");
            }
          }

        return true;
    }

    @Override
    public String setList(MyEvent e) {
            String str = "";
            ServeOneThread mysrv = e.mysrv;
            
            
            DAOPersone pm = new DAOPersone();
           // for (Object p : executeHQLQuery("from Persone")) {
            for (Object p : pm.getAllPersone()) {    
                hibernate.Persone pers = (hibernate.Persone) p;
                engine.Persone obj2 = new Persone();
                obj2.ID = pers.getId();
                obj2.FName = pers.getFname();
                obj2.LNmae = pers.getLname();

                Gson gson2 = new Gson();
                str += gson2.toJson(obj2);
                str += ",";
            }
            str = str.substring(0, str.length()-1);

            str = UserComman.commandGet("List", "[" + str + "]");
            try {
                mysrv.sendUser(str);
            } catch (Exception ex) {
                System.out.println("No Server");
                //  log.info("test" + e);
            }

        return str;
    }
    
    private FullPersone translate(hibernate.Persone person)
    {
        FullPersone obj2 = new FullPersone();
        obj2.ID = person.getId();
        obj2.FName = person.getFname();
        obj2.LName = person.getLname();
        obj2.bd = person.getBd();
        obj2.uid = person.getUid();
        obj2.Phones = getPhones(person);
        obj2.Addres = getAdddress(person);
        

        return obj2;
    }
    
    private int selectMaxIdPhone()
    {
      int digId = 0;
      for (Object p : executeHQLQuery("from Phone")) {
            hibernate.Phone pers = (hibernate.Phone) p;
            String id = pers.getId();
            if (Integer.parseInt(id) > digId){
              digId = Integer.parseInt(id);
            }
     }
      return digId;
    }
    
    private List<Phone> getPhones(hibernate.Persone person)  {
        List<Phone> Phones = new ArrayList<Phone>();

        for (hibernate.Phone pi : person.getPhone()) {
            engine.Phone p = new Phone();
            
              p.ID = pi.getId();
            
            p.Number = pi.getNphone();
            TypePhone pt = new TypePhone();
            pt.Type = pi.getTelcatId().getTelcat();
            p.Type = pt;
            Phones.add(p);
        }
  
        return Phones;
    }
    
    public List<Address> getAdddress(hibernate.Persone person) {
        List<Address> Addreses = new ArrayList<Address>();

        for (hibernate.Adres pi : person.getAdres()) {
            Address p = new Address();
            p.ID = pi.getId();
            Country country = new Country();
            country.name = pi.getCountryId().getNcountry();
            p.country = country;
            
            City city = new City();
            city.name = pi.getCityId().getNcity();
            p.city = city;
            
            Street street = new Street();
            street.name = pi.getStreetId().getNstreet();
            p.street = street;
            p.Add = pi.getAddt();
            
            TypeAdress tadr = new TypeAdress();
            tadr.Type = pi.getAdrcatId().getAdrcat();
            p.Type = tadr;

            Addreses.add(p);
        }
        return Addreses;
    }

    @Override
    public String getPersone(MyEvent evn) {
        String str ="";
        String id = evn.add;
        ServeOneThread mysrv = evn.mysrv;

        DAOPersone pm = new DAOPersone();
        hibernate.Persone person = pm.getPersoneById(id);

        FullPersone obj2 = translate(person);

        Gson gson2 = new Gson();
        str += gson2.toJson(obj2);

        str = UserComman.commandGet("Person", str);
        try {
            mysrv.sendUser(str);
        } catch (Exception e) {
            System.out.println("No Server");
            //  log.info("test" + e);
        }
        System.out.println(str);

        return str;
    }

      @Override
    public boolean sendPhoneT(MyEvent evn) {
      ServeOneThread mysrv = evn.mysrv;
   
        List<TypePhone> lpt = getPhoneT();

        Gson gson = new Gson();
        String send = UserComman.commandGet("PhoneT", gson.toJson(lpt));
        try {
          mysrv.sendUser(send);
        } catch (Exception e) {
          System.out.println("No Server");
        }

      return true;

    }
      
    private List executeHQLQuery(String hql) {
        List resultList = null;
        try {
            Session session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            Query q = session.createQuery(hql);
            resultList = q.list();
            session.getTransaction().commit();
        } catch (HibernateException he) {
            he.printStackTrace();
        }
        return resultList;
    }
    
    public List<TypePhone> getPhoneT() {
      List<TypePhone> pt = new ArrayList<TypePhone>();
      
       for (Object pi : executeHQLQuery("FROM Teltype")) {
          hibernate.Teltype adres = (hibernate.Teltype) pi;
          TypePhone t = new TypePhone();
          t.Type = adres.getTelcat();
          t.ID = adres.getTelcatId();
          pt.add(t);
      }
       
      return pt;
  }

    @Override
    public boolean sendAdrT(MyEvent evn) {

      ServeOneThread mysrv = evn.mysrv;
       List<TypeAdress> lpt = getAdrT();
       
       Gson gson = new Gson();
       String send = UserComman.commandGet("AddrT", gson.toJson(lpt));
       try {
           mysrv.sendUser(send);
       } catch (Exception e)
       {
         System.out.println("No Server");
       }
 
    return true;
    }
    
    public  List<TypeAdress> getAdrT()  {
      List<TypeAdress> pt = new ArrayList<TypeAdress>();
      
      for (Object pi : executeHQLQuery("FROM Adrtype")) {
          hibernate.Adrtype adres = (hibernate.Adrtype) pi;
          TypeAdress t = new TypeAdress();
          t.Type = adres.getAdrcat();
          pt.add(t);
      }
      return pt;
  }

    @Override
    public boolean sendCountry(MyEvent evn) {
      ServeOneThread mysrv = evn.mysrv;
      List<Country> lpt = getCountry();

      Gson gson = new Gson();
      String send = UserComman.commandGet("Country", gson.toJson(lpt));
      
      try {
        mysrv.sendUser(send);
      } catch (Exception e)
       {
         System.out.println("No Server");
       }
 
    return true;
    }
    
    public  List<Country> getCountry()  {
      List<Country> pt = new ArrayList<Country>();
      
      for (Object pi : executeHQLQuery("FROM Country")) {
          hibernate.Country adres = (hibernate.Country) pi;
          Country t = new Country();
          t.name = adres.getNcountry();
          t.ID = adres.getCountryId();
          pt.add(t);
      }
      return pt;
  }

    @Override
    public boolean sendCity(MyEvent evn) {
       ServeOneThread mysrv = evn.mysrv;
       String id = evn.add;
  
      List<City> lpt = getCityss(id);

      Gson gson = new Gson();
      String send = UserComman.commandGet("City", gson.toJson(lpt));
      try {
        mysrv.sendUser(send);
      } catch (Exception e)
       {
         System.out.println("No Server");
       }
 
    return true;
    }
    
      public List<City> getCityss(String id)  {
      List<City> pt = new ArrayList<City>();
      
      List query;
      if (id.equals("-1"))
      {
        query = executeHQLQuery("FROM City"); 
      }
      else{
        query = executeHQLQuery("FROM City WHERE country_id = '" + id + "'"); 
      }
      
      for (Object pi : query) {
          hibernate.City adres = (hibernate.City) pi;
          City t = new City();
          t.name = adres.getNcity();
          t.ID = adres.getCityId();
          pt.add(t);
      }
        
      return pt;
  }

    @Override
    public boolean sendStreet(MyEvent evn) {
       ServeOneThread mysrv = evn.mysrv;
       String id = evn.add;
  
      List<Street> lpt = getStreetss(id);

    Gson gson = new Gson();
    String send = UserComman.commandGet("Street", gson.toJson(lpt));
    try {
        mysrv.sendUser(send);
    } catch (Exception e)
       {
         System.out.println("No Server");
       }
  
    return true;
    }
    
    public List<Street> getStreetss(String id)  {
      List<Street> pt = new ArrayList<Street>();
      
      
      List query;
      if (id.equals("-1"))
      {
        query = executeHQLQuery("FROM Street");  
      }
      else {
        query = executeHQLQuery("FROM Street WHERE city_id = '" + id + "'"); 
      }
      
      for (Object pi : query) {
          hibernate.Street adres = (hibernate.Street) pi;
          Street t = new Street();
          t.name = adres.getNstreet();
          t.ID = adres.getStreetId();
          pt.add(t);
      }
      return pt;
  }
    private int selectMaxId()
    {
      int digId = 0;
      for (Object p : executeHQLQuery("from Persone")) {
            hibernate.Persone pers = (hibernate.Persone) p;
            String id = pers.getId();
            if (Integer.parseInt(id) > digId){
              digId = Integer.parseInt(id);
            }
     }
      return digId;
    }
    
    private hibernate.Persone translation2(FullPersone fp, ServeOneThread mysrv)
    {
        hibernate.Persone persone =  new hibernate.Persone();
        if (fp.ID != null)
            persone.setId(fp.ID);
        else {
          fp.ID  = Integer.toString(selectMaxId()+1);
            persone.setId(fp.ID);
        }
        
        persone.setFname(fp.FName);
        persone.setLname(fp.LName);
        persone.setBd(fp.bd);
        persone.setUid(mysrv.p.getId());
        
        List<hibernate.Phone> phones = new ArrayList<hibernate.Phone>();
        for (Phone p : fp.Phones){
            hibernate.Phone ph = new hibernate.Phone();
            if (p.ID != null)
              ph.setId(p.ID);
            else
              ph.setId(Integer.toString(selectMaxIdPhone()+1));
            ph.setNphone(p.Number);
            ph.setPersoneId(fp.ID);
            hibernate.Teltype tt = new hibernate.Teltype();
            hibernate.Teltype coun = (hibernate.Teltype)executeHQLQuery("FROM Teltype WHERE telcat = '" + p.Type.Type + "'").get(0); 
       String typeid = coun.getTelcatId();
            tt.setTelcatId(typeid);
            ph.setTelcatId(tt);
            phones.add(ph);
        }
        persone.setPhone(phones);
        
        List<hibernate.Adres> adr = new ArrayList<hibernate.Adres>();
        for (Address p : fp.Addres){
            hibernate.Adres ph = new hibernate.Adres();
            
            adr.add(ph);
        }
        persone.setAdres(adr);
        return persone;
    }

    @Override
    public boolean savePersone(MyEvent evn) {
      FullPersone fp = evn.fp;
      ServeOneThread mysrv = evn.mysrv;
      DAOPersone pm = new DAOPersone();
      hibernate.Persone persone = translation2(fp, mysrv);
      if (fp.ID != null)
        pm.updatePersone(persone);
      else
        pm.addPersone(persone);
    
    return true;
    }
    
    private int selectMaxIdTeltype()
    {
      int digId = 0;
      for (Object p : executeHQLQuery("from Teltype")) {
            hibernate.Teltype pers = (hibernate.Teltype) p;
            String id = pers.getTelcatId();
            if (Integer.parseInt(id) > digId){
              digId = Integer.parseInt(id);
            }
     }
      return digId;
    }

    @Override
    public boolean saveTypePhone(MyEvent evn) {
      TypePhone fp = evn.tp;
      hibernate.Teltype tp = new hibernate.Teltype();
      tp.setTelcat(fp.Type);
      tp.setTelcatId(Integer.toString(selectMaxIdTeltype()+1));
      DAOPersone pm = new DAOPersone();
      pm.addTypePhone(tp);
      return true;
    }

     private int selectMaxIdAdress()
    {
      int digId = 0;
      for (Object p : executeHQLQuery("from Adrtype")) {
            hibernate.Adrtype pers = (hibernate.Adrtype) p;
            String id = pers.getAdrcatId();
            if (Integer.parseInt(id) > digId){
              digId = Integer.parseInt(id);
            }
     }
      return digId;
    }

    @Override
    public boolean saveTypeAdress(MyEvent evn) {
        TypeAdress fp = evn.ta;
        ServeOneThread mysrv = evn.mysrv;
      
       int id = selectMaxIdAdress();
       id = id + 1;  
       
       Session sess = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = sess.beginTransaction();
        hibernate.Adrtype adrtype = new hibernate.Adrtype();
        adrtype.setAdrcatId(Integer.toString(id));
        adrtype.setAdrcat(fp.Type);
        sess.save(adrtype);
        tx.commit();
       
       return true;
    }
    
    private int selectMaxIdCountry()
    {
      int digId = 0;
      for (Object p : executeHQLQuery("from Country")) {
            hibernate.Country pers = (hibernate.Country) p;
            String id = pers.getCountryId();
            if (Integer.parseInt(id) > digId){
              digId = Integer.parseInt(id);
            }
     }
      return digId;
    }

    @Override
    public boolean saveCountry(MyEvent evn) {
      Country fp = evn.country;
      int id = selectMaxIdCountry();
      id = id + 1;
      
      Session sess = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = sess.beginTransaction();
        hibernate.Country country = new hibernate.Country();
        country.setCountryId(Integer.toString(id));
        country.setNcountry(fp.name);
        sess.save(country);
        tx.commit();
      return true;
    }
    
    private int selectMaxIdCity()
    {
      int digId = 0;
      for (Object p : executeHQLQuery("from City")) {
            hibernate.City pers = (hibernate.City) p;
            String id = pers.getCityId();
            if (Integer.parseInt(id) > digId){
              digId = Integer.parseInt(id);
            }
     }
      return digId;
    }

    @Override
    public boolean saveCity(MyEvent evn) {
      City fp = evn.city;
      int id = selectMaxIdCity();
      id = id + 1;
      
      Session sess = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = sess.beginTransaction();
        hibernate.City city = new hibernate.City();
        city.setCityId(Integer.toString(id));
        city.setNcity(fp.name);
        city.setCountryId(fp.OID);
        sess.save(city);
        tx.commit();

      return true;
    }
    
    private int selectMaxIdStreet()
    {
      int digId = 0;
      for (Object p : executeHQLQuery("from Street")) {
            hibernate.Street pers = (hibernate.Street) p;
            String id = pers.getCityId();
            if (Integer.parseInt(id) > digId){
              digId = Integer.parseInt(id);
            }
     }
      return digId;
    }

    @Override
    public boolean saveStreet(MyEvent evn) {
      Street fp = evn.street;
      int id = selectMaxIdStreet();
      id = id + 1;

      Session sess = HibernateUtil.getSessionFactory().openSession();
      Transaction tx = sess.beginTransaction();
      hibernate.Street street = new hibernate.Street();
      street.setStreetId(Integer.toString(id));
      street.setNstreet(fp.name);
      street.setCityId(fp.OID);
      sess.save(street);
      tx.commit();
      return true;
    }

    @Override
    public boolean delPersone(MyEvent evn) {
      FullPersone fp = evn.fp;
      ServeOneThread mysrv = evn.mysrv;
      DAOPersone pm = new DAOPersone();
      pm.deletePersone(translation2(fp, mysrv));
      return true;
    }

       @Override
    public boolean delPhone(MyEvent myEvent) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean delAdres(MyEvent myEvent) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean getFoto(MyEvent myEvent) {
        MyrealListener mr = new MyrealListener();
        mr.getFoto(myEvent);
        return true;
    }

  
  
  
}
